#include "Action.h"
#include "Machine.h"
#include "Logger.h"
#include "Tags.h"


Action::Action() 
: _machine(0)
{}

Action::~Action()
{}

void Action::SetSpecific(const StringMap& properities)
{}

void Action::SetObject(ObjectPtr object)
{
    _object = object;
    CookObject();
}

void Action::CookObject()
{}

void Action::Cancel()
{}

void Action::SetMachine(Machine* machine)
{
    _machine = machine;
}

void ResetAction::Perform()
{
    _object->Reset();    
}

void SendAction::Perform()
{
    _channel->Send(_object->Data());
}

void SendAction::SetSpecific(const StringMap& properties)
{
    _channel = _machine->Channel(properties[tag::AChannel]);
}

void AddCharAction::Perform()
{
    _object->Add(_machine->CurrentState()->CurrentChar());
}

void TimeoutAction::CookObject()
{
    if (_object->IsDigit())
        timer.setInterval(_object->ToInt());
    else
    {
        logger.addn("Timeout value is not a digit. Setting up 1 sec timeout."); //TODO: Make it good
        timer.setInterval(1000); //msec
    }  

    timer.setSingleShot(true);
    QObject::connect(&timer, SIGNAL(timeout()), _machine->ControlTape().get(), SLOT(PlaceTimeoutChar()));
}

void TimeoutAction::Perform()
{
    timer.start();
}

void TimeoutAction::Cancel()
{
    timer.stop();    
}

void CrcAction::Perform()
{}

void LogAction::Perform()
{
    QString log;
    
    for (StrRefList::const_iterator first = strings.constBegin(), last = strings.constEnd(); first != last; ++first)
        log.append(*first->string());
    
    logger.addn(log);
}

void LogAction::CookObject()
{
    QStringList tokens = QString(_object->Data()).split("%", QString::SkipEmptyParts);
    
    for (QStringList::const_iterator token = tokens.constBegin(), last = tokens.constEnd(); token != last; ++token)
        strings.append(_machine->IsEnvString(*token) ? _machine->EnvStringRef(*token) : new QString(*token));
}